package online_service

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"peilian-api/app/global/common"
	"peilian-api/app/global/databases/redisop"
	"peilian-api/app/global/databases/tables"
	"peilian-api/app/global/log"
	"peilian-api/app/global/variable"
	"peilian-api/app/model"
	"peilian-api/utils/sdk"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"

	"github.com/gin-gonic/gin"
)

func OptionService(ctx *gin.Context, op model.OptionParams) error {
	t := op.Type
	if t == 1 {
		sid := op.StartId
		eid := op.EndId
		st := []tables.RealQues{}
		if sid != 0 && eid != 0 {
			variable.DB.MySQL.Model(&tables.RealQues{}).Where("id >= ? and id <= ?", sid, eid).Find(&st)
		}
		for i := 0; i < len(st); i++ {
			if len(st[i].AnswerAudio) == 0 {
				continue
			}
			pcmUrl := st[i].AnswerAudio
			pcmUrl = strings.Replace(pcmUrl, ".pcm", ".mp3", -1)
			s := strings.Split(pcmUrl, "/")

			p := variable.Config.UfsInfo.UfsUrl + st[i].AnswerAudio
			out := s[len(s)-1:][0]
			if !FfmpegToMp3(p, out) {
				fmt.Println("转存失败")
			}

			dateTime := time.Now().Format("2006-01-02")
			fileName := fmt.Sprintf("%s/static/mp3/%s/%s", variable.Config.UfsInfo.BucketPrefix, dateTime, out)
			b, _ := ioutil.ReadFile(out)
			if err := sdk.IOput(b, fileName, "audio/mpeg"); err != nil {
				log.Logger.ErrorF(ctx, "文件转存失败：fileName:"+fileName)
				return fmt.Errorf("文件转存失败：fileName:" + fileName)
			}
			// os.Remove(out)
			// 更新数据
			if err := tables.UpdateMapById(map[string]interface{}{"audio": variable.Config.UfsInfo.UfsUrl + fileName}, int(st[i].ID)); err != nil {
				log.Logger.ErrorF(ctx, "文件更新失败:"+fileName)
				return err
			}
		}
	}
	return nil
}

// pcm转MP3并更新数据库
func OptionFfmpegToMp3(pcmUrl string, id int) (string, error) {
	s := strings.Split(pcmUrl, "/")
	out := s[len(s)-1:][0]
	out = strings.Replace(out, ".pcm", ".mp3", -1)
	if !FfmpegToMp3(pcmUrl, out) {
		return "", fmt.Errorf("视频转存失败")
	}
	// 文件上传
	fileName := fmt.Sprintf("%s/static/mp3/%s/%s", variable.Config.UfsInfo.BucketPrefix, time.Now().Format("2006-01-02"), out)
	b, _ := ioutil.ReadFile(out)
	if err := sdk.IOput(b, fileName, "audio/mpeg"); err != nil {
		return "", fmt.Errorf("文件转存失败：fileName:" + fileName)
	}
	os.Remove(out)
	return out, nil
}

func FfmpegToMp3(originUrl string, out string) bool {
	cmdArguments := []string{"-y", "-ac", "1", "-ar", "16000", "-f", "s16le", "-i", originUrl, "-c:a", "libmp3lame", "-q:a", "2", out}
	c := exec.Command("ffmpeg", cmdArguments...)
	err := c.Run()
	return err == nil
}

// func ManualOptData(ctx *gin.Context, osp model.OptionSchameParams) (int64, error) {
// 	var typ = osp.Type
// 	var id = osp.Id
// 	if typ == 1 {
// 		agent_service.CalculationServiceTime()
// 	}
// 	if typ == 2 {
// 		new(conf_service.ConstituteService).SetRedisConsituteKey()
// 	}
// 	if typ == 3 {
// 		count, err := new(career_service.CareerService).SetRedisSpecialKey()
// 		if err != nil {
// 			return count, err.Err
// 		}
// 		return count, nil
// 	}
// 	if typ == 4 {
// 		new(career_service.SpecialService).SetSpecialCareerList()
// 		return 0, nil
// 	}
// 	if typ == 5 {
// 		err := new(career_service.SpecialService).UpdateScore(ctx, id)
// 		if err != nil {
// 			log.Logger.ErrorF(ctx, fmt.Sprintf("计算得分 err info: %s", err.Error()))
// 			return 0, err
// 		}
// 		return 1, nil
// 	}
// 	if typ == 6 {
// 		var cnt int64
// 		if err := new(career_service.CareerService).SetHistoryWebReport(ctx, &cnt); err != nil {
// 			log.Logger.ErrorF(ctx, err.Error())
// 			return 0, err
// 		}
// 		return cnt, nil
// 	}

// 	if typ == 7 {
// 		JudgeNoPcmNoMp3(ctx)
// 	}

// 	if typ == 8 { // 是否开启上新弹窗
// 		cc, _ := new(tables.CommonConf).FetchByConfKey(tables.ConfKeyTopicNew)
// 		redisop.SetStr(ctx, common.RedisTopicNewNotify, cc[0].ConfValue, -1)
// 	}

// 	// if typ == 8 {
// 	// 	s, _ := new(report_service.MaskService).MaskWords(ctx, id)
// 	// 	if s != "" {
// 	// 		return 1, nil
// 	// 	}
// 	// 	return 0, nil
// 	// }

// 	return 0, nil
// }

// 扫描一场报告中，pcm和mp3未生成现象
func JudgeNoPcmNoMp3(ctx *gin.Context) {
	for {
		sc := variable.DB.Redis.LPop(common.RedisSessionMp3Queue)
		s, _ := sc.Result()
		if len(s) == 0 {
			time.Sleep(5 * time.Second)
			continue
		}
		sessionId, _ := strconv.Atoi(s)
		// 测试
		log.Logger.Info(fmt.Sprintf("消费RedisSessionMp3Queue队列:%d", sessionId))
		srList, _ := new(tables.RealQues).GetRealQuesBySessionId(sessionId)
		time.Sleep(2 * time.Second)
		for _, v := range srList {
			pcmName := v.AnswerAudio
			if utf8.RuneCountInString(pcmName) == 0 || pcmName == "" {
				// 报警，人工介入处理
				msgInfo := fmt.Sprintf("pcm不存在,session:%d, qid:%d", v.SessionID, v.ID)
				sdk.SendMsg(msgInfo)
			} else {
				if utf8.RuneCountInString(v.Audio) == 0 || v.Audio == "" {
					// 自行处理
					fileName := strings.Replace(pcmName, ".pcm", ".mp3", -1)
					fileName = strings.Replace(fileName, "/video/", "/mp3/", -1)
					filePrefix := variable.Config.UfsInfo.UfsUrl + variable.Config.UfsInfo.BucketPrefix
					_, err := OptionFfmpegToMp3(filePrefix+pcmName, int(v.ID))
					if err != nil {
						// 报警
						msgInfo := fmt.Sprintf("mp3转存失败,session:%d, qid:%d, 已经重试", v.SessionID, v.ID)
						sdk.SendMsg(msgInfo)
						variable.DB.Redis.RPush(common.RedisSessionMp3Queue, sessionId)
					} else {
						variable.DB.MySQL.Model(&tables.RealQues{}).Where("id = ?", v.ID).
							Update("audio", filePrefix+fileName)
						msgInfo := fmt.Sprintf("mp3更新,session:%d, qid:%d, %s", v.SessionID, v.ID, filePrefix+fileName)
						sdk.SendMsg(msgInfo)
					}
				}
			}
		}

	}

}

// 缓存是否开启题目上新
func SetRedisTopicNew(ctx *gin.Context) error {
	// 1. 查询是否开启 上新功能
	cc, _ := new(tables.CommonConf).FetchByConfKey(tables.ConfKeyTopicNew)
	err := redisop.SetStr(ctx, common.RedisTopicNewNotify, cc[0].ConfValue, -1)
	if err != nil {
		return err // 操作失败
	}
	return nil
}
